<?php

namespace common\models\c2\entity;

use common\helpers\CodeGenerator;
use kzo\user\models\BeUser;
use Yii;
use yii\behaviors\BlameableBehavior;
use yii\helpers\ArrayHelper;
use yii\validators\RequiredValidator;

/**
 * This is the model class for table "{{%sales_order}}".
 *
 * @property string $id
 * @property integer $type
 * @property string $code
 * @property string $label
 * @property string $customer_id
 * @property string $production_date
 * @property string $delivery_date
 * @property string $grand_total
 * @property string $created_by
 * @property string $updated_by
 * @property string $memo
 * @property integer $state
 * @property integer $status
 * @property string $created_at
 * @property string $updated_at
 */
class SalesOrder extends \kzo\base\models\ActiveRecord
{

    public $items;

    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return '{{%sales_order}}';
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['type', 'customer_id', 'created_by', 'updated_by', 'state', 'status'], 'integer'],
            [['code', 'customer_id'], 'required'],
            [['items'], 'validateItems'],
            [['production_date', 'delivery_date', 'created_at', 'updated_at', 'items'], 'safe'],
            [['grand_total'], 'number'],
            [['code', 'label', 'memo'], 'string', 'max' => 255],
        ];
    }

    public function behaviors()
    {
        return ArrayHelper::merge(parent::behaviors(), [
            BlameableBehavior::className()
        ]); // TODO: Change the autogenerated stub
    }

    public function validateItems($attribute) {
        $requiredValidator = new RequiredValidator();
        foreach ($this->$attribute as $index => $row) {
            $error = null;
            $requiredValidator->validate($row['product_id'], $error);
            if (!empty($error)) {
                $key = $attribute . '[' . $index . '][product_id]';
                $this->addError($key, Yii::t('app.c2', '{attribute} can not be empty!', ['attribute' => Yii::t('app.c2', 'Product')]));
            }
            $requiredValidator->validate($row['product_sku_id'], $error);
            if (!empty($error)) {
                $key = $attribute . '[' . $index . '][product_sku_id]';
                $this->addError($key, Yii::t('app.c2', '{attribute} can not be empty!', ['attribute' => Yii::t('app.c2', 'Product Sku')]));
            }
        }
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'id' => Yii::t('app.c2', 'ID'),
            'type' => Yii::t('app.c2', 'Type'),
            'code' => Yii::t('app.c2', 'Code'),
            'label' => Yii::t('app.c2', 'Label'),
            'customer_id' => Yii::t('app.c2', 'Customer ID'),
            'production_date' => Yii::t('app.c2', 'Production Date'),
            'delivery_date' => Yii::t('app.c2', 'Delivery Date'),
            'grand_total' => Yii::t('app.c2', 'Grand Total'),
            'created_by' => Yii::t('app.c2', 'Created By'),
            'updated_by' => Yii::t('app.c2', 'Updated By'),
            'memo' => Yii::t('app.c2', 'Memo'),
            'state' => Yii::t('app.c2', 'State'),
            'status' => Yii::t('app.c2', 'Sales Order Status'),
            'created_at' => Yii::t('app.c2', 'Created At'),
            'updated_at' => Yii::t('app.c2', 'Updated At'),
        ];
    }

    /**
     * @inheritdoc
     * @return \common\models\c2\query\SalesOrderQuery the active query used by this AR class.
     */
    public static function find()
    {
        return new \common\models\c2\query\SalesOrderQuery(get_called_class());
    }
    
    /**
    * setup default values
    **/
    public function loadDefaultValues($skipIfSet = true) {
        parent::loadDefaultValues($skipIfSet);
        if ($this->isNewRecord) {
            $this->code = CodeGenerator::getCodeByDate($this, 'SO');
        }
    }

    public function getCustomer()
    {
        return $this->hasOne(FeUser::className(), ['id' => 'customer_id']);
    }

    public function getCreator()
    {
        return $this->hasOne(BeUser::className(), ['id' => 'created_by']);
    }

    public function getUpdater()
    {
        return $this->hasOne(BeUser::className(), ['id' => 'updated_by']);
    }

    public function getOrderItems()
    {
        return $this->hasMany(SalesOrderItem::className(), ['sales_order_id' => 'id']);
    }

    public function loadItems()
    {
        $this->items = $this->getOrderItems()->all();
    }

    public function afterSave($insert, $changedAttributes)
    {
        parent::afterSave($insert, $changedAttributes); // TODO: Change the autogenerated stub
        $grand_total = 0.000;
        if (!empty($this->items)) {
            foreach ($this->items as $item) {
                $pieces = isset($item['pieces']) ? $item['pieces'] : 0;
                $price = isset($item['price']) ? $item['price'] : 0;
                $attributes = [
                    'product_id' => isset($item['product_id']) ? $item['product_id'] : 0,
                    'product_sku_id' => isset($item['product_sku_id']) ? $item['product_sku_id'] : 0,
                    'package_id' => isset($item['package_id']) ? $item['package_id'] : 0,
                    'measure_id' => isset($item['measure_id']) ? $item['measure_id'] : 0,
                    'pieces' => $pieces,
                    'price' => $price,
                    'quantity' => 0,
                    'send_pieces' => 0,
                    'subtotal' => 0,
                    'memo' => isset($item['memo']) ? $item['memo'] : '',
                    'position' => isset($item['position']) ? $item['position'] : 0,
                ];

                if (($model = Product::findOne($item['product_id'])) != null) {
                    $attributes['product_label'] = $model->label;
                }

                if (($model = ProductSku::findOne($item['product_id'])) != null) {
                    $attributes['sku_label'] = $model->label;
                }

                if (($model = ProductPackage::findOne($item['product_id'])) != null) {
                    $attributes['package_label'] = $model->label;
                }

                $package = ProductPackage::findOne($item['package_id']);
                if (!is_null($package)) {
                    $attributes['quantity'] = $package->capacity * $pieces;
                    $attributes['subtotal'] = $price * $attributes['quantity'];
                    $grand_total += $attributes['subtotal'];
                }

                if (isset($item['id']) && $item['id'] == '') {
                    $itemModel = new SalesOrderItem();
                    $itemModel->setAttributes($attributes);
                    $itemModel->link('owner', $this);
                } else {
                    $itemModel = SalesOrderItem::findOne($item['id']);
                    if (!is_null($itemModel)) {
                        $itemModel->updateAttributes($attributes);
                    }
                }
            }
        }

        $this->updateAttributes(['grand_total' => $grand_total]);

    }

    public function beforeDelete()
    {
        foreach ($this->getOrderItems()->all() as $item) {
            $item->delete();
        }
        return parent::beforeDelete(); // TODO: Change the autogenerated stub
    }

}
